# -*- coding: utf-8 -*-
#
# Copyright (c) 2012, Rafael Pivato
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Rafael Pivato nor the names of its contributors
#       may be used to endorse or promote products derived from this
#       software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL RAFAEL PIVATO BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import bcoma
import logging
import webapp2
import wowgae

from google.appengine.api import taskqueue
from wowgae.model import Guild
from wowgae.model import Account
from wowgae.model import Character


class GuildUpdatingTask(webapp2.RequestHandler):
    """Updates current guild and members information."""

    def get(self):
        self.post()

    def post(self):
        logging.debug('Starting Guild Updating task.')
        try:
            guild = bcoma.Guild.fetch_members('goldrinn',
                                              'discípulos de cenarius')
        except Exception as download_ex:
            logging.warn('Download of members data failed. %s' % \
                          (download_ex))
            raise download_ex
        else:
            logging.debug('Updating datastore with downloaded data.')
            try:
                ranks = self.app.config.get('wowgae.ranks')
                Guild.update(guild, ranks)
            except Exception as update_ex:
                logging.error('Datastore update error. %s' % (update_ex))
                raise update_ex
            else:
                logging.info('Guild Updating process successfully finished.')


class UpdateAccountMembershipTask(webapp2.RequestHandler):
    """Updates all account information with correct member_until data."""

    def get(self):
        self.post()

    def post(self):
        logging.debug('Starting Account Membership update task.')
        processed = 0
        total = 0
        try:
            query = Account.all()
            for entity in query.run():
                if not entity.member_until:
                    character = Character.get_by_name(entity.name)
                    entity.member_until = character.member_until
                    entity.put()
                    processed += 1
                total += 1
        except Exception as ex:
            logging.error(('Account membership updating failed after ' + \
                          'processing %s missing membership data of %s ' + \
                          'accounts. %s') % (processed, total, ex))
        else:
            logging.info(('Account Membership update task finished ' + \
                          'after processing %s missing membership ' + \
                          'data of %s accounts.') % (processed, total))


class Job(webapp2.RequestHandler):
    """General cron job."""

    def initialize(self, request, response):
        webapp2.RequestHandler.initialize(self, request, response)
        self.tasks = self.get_tasks()

    def _task_uri(self, name):
        router = wowgae.task.router
        return router.build(self.request, name, [], {})

    def _enqueue_tasks(self):
        for task in self.tasks:
            logging.info('Queueing task "%s".' % (task))
            uri = self._task_uri(task)
            taskqueue.add(url=uri, queue_name='bcoma')

    def get_tasks(self):
        """Method to be overriden, must return the name of the tasks."""
        return []

    def get(self):
        job_name = self.__class__.__name__
        logging.debug('Starting job %s.' % (job_name))
        try:
            self._enqueue_tasks()
        except Exception as ex:
            logging.error('Error with job %s. %s' % (job_name, ex))
        else:
            logging.info('Finished job %s with no error.' % (job_name))


class HourlyJob(Job):
    """To be called as a hourly cron job."""

    def get_tasks(self):
        return [
            'activations',
        ]


class DailyJob(Job):
    """To be called as a daily cron job."""

    def get_tasks(self):
        """Runs the daily job."""
        return [
            'guildupdating',
        ]


class WeeklyJob(Job):
    """To be called as a weekly cron job."""

    def get_tasks(self):
        """Runs the weekly job."""
        return [
            'updateaccountmembership',
        ]
